/**
 * @file wa_cursor.c
 *
 */

 /*********************
 *      INCLUDES
 *********************/
#include "wa_conf.h"
#if USE_WA_CURSOR != 0
#include "wa_cursor.h"

 /*********************
 *      DEFINES
 *********************/

 /**********************
 *      TYPEDEFS
 **********************/

 /**********************
 *  STATIC PROTOTYPES
 **********************/
static wa_obj_callback ancestor_callback;
static void wa_cursor_callback(wa_sign* sign);
/**********************
 *  STATIC VARIABLES
 **********************/


 /**********************
 *      MACROS
 **********************/

 /**********************
 *   GLOBAL FUNCTIONS
 **********************/
 /**
 * cursor module init
 */
void wa_cursor_module_init(void)
{
}

/**
* create a cursor
* @param par
* @return cursor obj
*/
wa_obj* wa_cursor_create(wa_obj* par)
{
	wa_obj* new_cursor;
	wa_cursor_ext* cursor_ext;

	new_cursor = wa_obj_create(par, NULL);
	if (new_cursor == NULL)
	{
		return new_cursor;
	}

	if (ancestor_callback == NULL)
	{
		ancestor_callback = wa_obj_get_callback(new_cursor);
	}
	cursor_ext = wa_obj_malloc_ext_attr(new_cursor, sizeof(wa_cursor_ext));

	cursor_ext->type = WA_CURSOR_TYPE_TRIA;
	cursor_ext->fore_color = WA_COLOR_FOREGROUND;
	cursor_ext->back_color = WA_COLOR_BACKGROUND;

	cursor_ext->round_r = 2;
	cursor_ext->tria_dir = WA_CURSOR_TRIA_RIGHT;
	cursor_ext->tria_type = WA_CURSOR_TRIA_FILL;

	wa_obj_set_callback(new_cursor, wa_cursor_callback);

	return new_cursor;
}

/**
* cursor set type
* @param cursor
* @param type
*/
void wa_cursor_set_type(wa_obj* cursor, wa_cursor_type type)
{
	wa_cursor_ext* ext;
	ext = wa_obj_get_ext_attr(cursor);
	ext->type = type;
	wa_obj_invalidate(cursor);
}

/**
* cursor set fore color
* @param cursor
* @param fore color
*/
void wa_cursor_set_fore_color(wa_obj* cursor, wa_gui_color fore_color)
{
	wa_cursor_ext* ext;
	ext = wa_obj_get_ext_attr(cursor);
	ext->fore_color = fore_color;
	wa_obj_invalidate(cursor);
}

/**
* cursor set back color
* @param cursor
* @param back color
*/
void wa_cursor_set_back_color(wa_obj* cursor, wa_gui_color back_color)
{
	wa_cursor_ext* ext;
	ext = wa_obj_get_ext_attr(cursor);
	ext->back_color = back_color;
	wa_obj_invalidate(cursor);
}

/**
* cursor set round r
* @param cursor
* @param round r
*/
void wa_cursor_set_round_r(wa_obj* cursor, uint32_t round_r)
{
	wa_cursor_ext* ext;
	ext = wa_obj_get_ext_attr(cursor);
	ext->round_r = round_r;
	wa_obj_invalidate(cursor);
}

/**
* cursor set tria dir
* @param cursor
* @param tria dir
*/
void wa_cursor_set_tria_dir(wa_obj* cursor, wa_cursor_tria_direction tria_dir)
{
	wa_cursor_ext* ext;
	ext = wa_obj_get_ext_attr(cursor);
	ext->tria_dir = tria_dir;
	wa_obj_invalidate(cursor);
}

/**
* cursor set tria type
* @param cursor
* @param tria type
*/
void wa_cursor_set_tria_type(wa_obj* cursor, wa_cursor_tria_type tria_type)
{
	wa_cursor_ext* ext;
	ext = wa_obj_get_ext_attr(cursor);
	ext->tria_type = tria_type;
	wa_obj_invalidate(cursor);
}

/**
* cursor get type
* @param cursor
* @return type
*/
wa_cursor_type wa_cursor_get_type(wa_obj* cursor)
{
	wa_cursor_ext* ext;
	ext = wa_obj_get_ext_attr(cursor);
	return ext->type;
}

/**
* cursor get fore color
* @param cursor
* @return fore color
*/
wa_gui_color wa_cursor_get_fore_color(wa_obj* cursor)
{
	wa_cursor_ext* ext;
	ext = wa_obj_get_ext_attr(cursor);
	return ext->fore_color;
}

/**
* cursor get back color
* @param cursor
* @return back color
*/
wa_gui_color wa_cursor_get_back_color(wa_obj* cursor)
{
	wa_cursor_ext* ext;
	ext = wa_obj_get_ext_attr(cursor);
	return ext->back_color;
}

/**
* cursor get round r
* @param cursor
* @return round r
*/
uint32_t wa_cursor_get_round_r(wa_obj* cursor)
{
	wa_cursor_ext* ext;
	ext = wa_obj_get_ext_attr(cursor);
	return ext->round_r;
}

/**
* cursor get tria dir
* @param cursor
* @return tria dir
*/
wa_cursor_tria_direction wa_cursor_get_tria_dir(wa_obj* cursor)
{
	wa_cursor_ext* ext;
	ext = wa_obj_get_ext_attr(cursor);
	return ext->tria_dir;
}

/**
* cursor get tria type
* @param cursor
* @return tria type
*/
wa_cursor_tria_type wa_cursor_get_tria_type(wa_obj* cursor)
{
	wa_cursor_ext* ext;
	ext = wa_obj_get_ext_attr(cursor);
	return ext->tria_type;
}

/**********************
*   STATIC FUNCTIONS
**********************/
/**
* cursor redraw functions
* @param obj
*/
static void _Paint(wa_obj* obj)
{
	int w, h;
	wa_cursor_ext* ext;
	ext = wa_obj_get_ext_attr(obj);
	w = wa_obj_get_width(obj);
	h = wa_obj_get_height(obj);
	if (ext->type == WA_CURSOR_TYPE_TRIA)
	{
		wa_mask_draw_triangle_dir dir;
		wa_mask_fillrect(obj->rect.x1, obj->rect.y1, w, h, &(obj->redraw_rect), ext->back_color);
		if (ext->tria_dir == WA_CURSOR_TRIA_UP)
		{
			dir = WA_MASK_DRAW_TRIA_UP;
		}
		else if (ext->tria_dir == WA_CURSOR_TRIA_DOWN)
		{
			dir = WA_MASK_DRAW_TRIA_DOWN;
		}
		else if (ext->tria_dir == WA_CURSOR_TRIA_LEFT)
		{
			dir = WA_MASK_DRAW_TRIA_LEFT;
		}
		else if (ext->tria_dir == WA_MASK_DRAW_TRIA_RIGHT)
		{
			dir = WA_MASK_DRAW_TRIA_RIGHT;
		}
		else
		{
			dir = WA_MASK_DRAW_TRIA_RIGHT;
		}
		if (ext->tria_type == WA_CURSOR_TRIA_DRAW)
		{
			wa_mask_drawtriangle(obj->rect.x1, obj->rect.y1, w, h, dir, &(obj->redraw_rect), ext->fore_color);
		}
		else if (ext->tria_type == WA_CURSOR_TRIA_FILL)
		{
			wa_mask_filltriangle(obj->rect.x1, obj->rect.y1, w, h, dir, &(obj->redraw_rect), ext->fore_color);
		}
	}
	else if (ext->type == WA_CURSOR_TYPE_INV_RECT)
	{
		wa_mask_inverse_rect(obj->rect.x1, obj->rect.y1, w, h, &(obj->redraw_rect));
	}
	else if (ext->type == WA_CURSOR_TYPE_INV_ROUNDRECT)
	{
		wa_mask_inverse_roundrect(obj->rect.x1, obj->rect.y1, w, h, ext->round_r, &(obj->redraw_rect));
	}
	else
	{
		wa_mask_fillrect(obj->rect.x1, obj->rect.y1, w, h, &(obj->redraw_rect), ext->back_color);
	}
}

/**
 * cursor obj delete function
 * @param obj
 */
static void _Delete(wa_obj* obj)
{
}

/**
 * cursor obj callback function
 * @param sign
 */
static void wa_cursor_callback(wa_sign* sign)
{
	int sign_id;
	wa_obj* obj;

	ancestor_callback(sign);
	sign_id = sign->sign_id;
	obj = sign->obj_dst;

	switch (sign_id)
	{
		case WA_SIGNAL_PAINT:
		{
			_Paint(obj);
			break;
		}
		case WA_SIGNAL_DELETE:
		{
			_Delete(obj);
			break;
		}
		default:
		{
			break;
		}
	}
}

#endif
